;;;
;;; JaCoLiB
;;; Copyright (C) 2008 Alessandro Serra
;;; 
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;; 
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;; 
;;; You should have received a copy of the GNU General Public License
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;;

;;;; Created on 2008-07-25 21:15:39

(in-package :jacolib)

(defclass jacolib ()
  ((shell
    :TYPE shell
    :INITARG :shell
    :READER jacolib-shell
    :INITFORM (make-instance 'cl-shell))
   (remote-shells
    :ACCESSOR jacolib-remote-shells
    :INITFORM (make-hash-table :test 'equal)))
  (:documentation "The jacolib system."))

; reg/unreg functions

(defun jacolib-register-shell-channel (jacolib channel)
  (setf (gethash (shell-channel-name channel) (jacolib-remote-shells jacolib)) channel)
  (rpc-channel-set-quit%-handler channel
                                #'(lambda ()
                                    (jacolib-unregister-shell-channel jacolib channel))))

(defun jacolib-unregister-shell-channel (jacolib channel)
  (remhash (shell-channel-name channel) (jacolib-remote-shells jacolib)))

; new channel

(defun jacolib-new-shell-channel (jacolib name)
  (let* ((channel (make-instance 'shell-channel
                                 :name name
                                 :shell (jacolib-shell jacolib))))
    (jacolib-register-shell-channel jacolib channel)
    channel))
 
; get remote shell

(defun jacolib-get-remote-shell (jacolib name)
  (let ((channel (gethash name (jacolib-remote-shells jacolib))))
    (if channel
        (rpc-channel-client channel))))

(defun jacolib-get-remote-shell-by-language-name (jacolib language-name)
  (with-hash-table-iterator (generator-fn (jacolib-remote-shells jacolib))
                            (loop     
                             (multiple-value-bind (more? key value) (generator-fn)
                               (declare (ignore key))
                               (unless more? (return nil))
                               (when (string-equal (shell-language-name (rpc-channel-client value)) language-name)
                                 (return (rpc-channel-client value)))))))
                            